package cn.tedu.mall.book.service.impl;

import cn.tedu.mall.book.entity.User;
import cn.tedu.mall.book.ex.ServiceException;
import cn.tedu.mall.book.mapper.UserMapper;
import cn.tedu.mall.book.pojo.dto.UserAddNewDTO;
import cn.tedu.mall.book.pojo.dto.UserLoginDTO;
import cn.tedu.mall.book.pojo.dto.UserUpdateDTO;
import cn.tedu.mall.book.pojo.vo.UserSimpleVO;
import cn.tedu.mall.book.pojo.vo.UserStandardVO;
import cn.tedu.mall.book.service.IUserService;
import cn.tedu.mall.book.util.IPUtil;
import cn.tedu.mall.book.util.PasswordEncoder;
import cn.tedu.mall.book.web.JsonPage;
import cn.tedu.mall.book.web.State;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
public class UserServiceImpl implements IUserService {
    @Autowired
    UserMapper userMapper;

    @Autowired
    IPUtil ipUtil;

    @Autowired
    PasswordEncoder passwordEncoder;

    //插入数据库一个用户
    @Override
    public void insertUser(UserAddNewDTO user) {
        String username=user.getUsername();
        //获取数据库中的user对象
        UserSimpleVO userVO=userMapper.selectByUsername(username);
        //判断查询到的用户名是否为null
        //如果不为null，用户名在数据库中已存在，则抛出异常
        if (userVO!=null){
            log.error("此账号已经被占用，将抛出异常");
            throw new ServiceException(State.ERR_NAME_DUPLICATE,"注册失败，用户名（" + username + "）已经被占用！");
        }
        //如果用户名不存在，则添加到数据库中
        User u=new User();
        //将UserAddNewDTO对象的属性添加到User中
        BeanUtils.copyProperties(user,u);
        // 日志
        log.trace("此账号未被占用，准备向表中写入此次添加的管理员信息");
        // 通过参数获取原密码
        String password = user.getPassword();
        //log.debug("原密码=" + password);
        // 通过加密方式，得到加密后的密码encodedPassword
        String encodedPassword = passwordEncoder.encode(password);
        u.setPassword(encodedPassword);
        log.debug("加密前的密码：{}，加密后的密码：{}", password, encodedPassword);
        // 创建当前时间对象now > LocalDateTime.now()
        LocalDateTime now = LocalDateTime.now();
        u.setLastLoginTime(now);
        //设置用户登录的ip
        u.setLastLoginIp(ipUtil.getLocalIpAddress());
        u.setIsEnable(1);
        u.setGmtCreate(now);
        u.setGmtModified(now);
        //将u插入到数据库中
        int rows=userMapper.insertUser(u);
        // 判断以上返回的结果是否不为1，抛出InsertException异常
        if (rows != 1) {
            throw new ServiceException(State.ERR_INSERT,"注册失败，服务器忙，请稍后再次尝试！");
        }
        log.debug("user >>"+u);
    }

    //修改用户个人信息
    @Override
    public void updateById(UserUpdateDTO userUpdateDTO) {
        userUpdateDTO.setGmtModified(LocalDateTime.now());
        userMapper.updateById(userUpdateDTO);
    }

    // 分页查询用户列表
    @Override
    public JsonPage<UserStandardVO> getUserList(Integer page, Integer pageSize) {
        PageHelper.startPage(page,pageSize);
        List<UserStandardVO> userList = userMapper.getUserList();
        PageInfo<UserStandardVO> pageInfo = new PageInfo<>(userList);
        return JsonPage.restPage(pageInfo);
    }

    /* 实现登录业务 */
    @Override
    public UserStandardVO loginUser(UserLoginDTO userLoginDTO, HttpSession session) {
        //获取用户提交的username
        String username=userLoginDTO.getUsername();
        //判断数据库中是否存在该username的对象
        UserSimpleVO queryResult=userMapper.selectByUsername(username);
        //如果用户为空，说明用户名不存在
        if (queryResult==null){
            // 是：表示用户名不存在，抛出异常
            log.warn("登录失败，用户名不存在！");
            throw new ServiceException(State.ERR_NOT_FOUND,"登录失败，用户名不存在！");
        }
        // 【如果程序可以执行到此步，则可以确定未抛出异常，即查询结果不为null】
        // 【以下可视为：存在与用户名匹配的用户数据】
        // 判断查询结果中的isEnable属性值是否不为1
        log.debug("第2步：判断用户名是否存在此账号是否处于启用状态");
        if (queryResult.getIsEnable()!= 1) {
            // 是：表示此用户状态是【禁用】的，则抛出UserStateException异常
            log.warn("登录失败，此账号已经被禁用！");
            throw new ServiceException(State.ERR_USER_NAME_DISABLE,"登录失败，此账号已经被禁用！");
        }
        // 【如果程序可以执行到此步，表示此用户状态是【启用】的】
        // 从参数中取出此次登录时客户端提交的密码
        log.debug("第3步：判断密码是否正确");
        String rawPassword = userLoginDTO.getPassword();
        // 调用PasswordEncoder对象的matches()方法，对客户端提交的密码和查询结果中的密码进行验证
        boolean matchResult = passwordEncoder.matches(rawPassword, queryResult.getPassword());
        // 判断以上验证结果
        if (!matchResult) {
            // false：密码错误，视为登录失败，则抛出PasswordNotMatchException异常
            log.warn("登录失败，密码错误！");
            throw new ServiceException(State.ERR_NOT_FOUND,"登录失败，密码错误！");
        }
        // 密码正确，视为登录成功
        //把当前登录成功的用户对象保存到会话对象中
        session.setAttribute("user",queryResult);
        System.out.println(session.getAttribute("user"));
        // 将查询结果中的password、isEnable设置为null，避免响应到客户端
        UserStandardVO userStandardVO = userMapper.getById(queryResult.getId());
        // 返回查询结果
        log.debug("登录成功，即将返回：{}", queryResult);
        return userStandardVO;
    }

}
